#include <stdio.h>
#include <string.h>
#include <stdbool.h>

#include "acl.h"

// 每行最大长度
#define LINE_MAX 1024

void mask_ip(u_int32_t *ip, int mask)
{
    for (int i = mask; i < 32; i++)
    {
        *ip &= ~(1 << i);
    }
}

int read_line(char *path, struct FILTER *p_filter)
{
    struct FILTER *cur_p_filter = p_filter;
    FILE *fp;
    int line_num = 0;         // 文件行数
    int line_len = 0;         // 文件每行的长度
    char buf[LINE_MAX] = {0}; // 行数据缓存

    fp = fopen(path, "r");
    if (NULL == fp)
    {
        printf("open %s failed.\n", path);
        return -1;
    }

    while (fgets(buf, LINE_MAX, fp))
    {
        line_num++;
        line_len = strlen(buf);
        // 排除换行符
        if ('\n' == buf[line_len - 1])
        {
            buf[line_len - 1] = '\0';
            line_len--;
            if (0 == line_len)
            {
                //空行
                continue;
            }
        }
        // windos文本排除回车符
        if ('\r' == buf[line_len - 1])
        {
            buf[line_len - 1] = '\0';
            line_len--;
            if (0 == line_len)
            {
                //空行
                continue;
            }
        }

        struct FILTER *filter = (struct FILTER *)malloc(sizeof(struct FILTER));

        // printf("%s\n", buf);
        char action[10];
        char sour_ip[18] = {0};
        char dest_ip[18] = {0};

        sscanf(buf, "%s source %s %d %d destination %s %d %d\n", action, sour_ip, &(filter->sour_filter.mask), &(filter->sour_filter.port), dest_ip, &(filter->dest_filter.mask), &(filter->dest_filter.port));
        filter->sour_filter.ip.s_addr = inet_addr(sour_ip);
        filter->dest_filter.ip.s_addr = inet_addr(dest_ip);

        mask_ip(&(filter->sour_filter.ip.s_addr), filter->sour_filter.mask);
        mask_ip(&(filter->dest_filter.ip.s_addr), filter->dest_filter.mask);

        printf("filted_ip:%s %d  %s %d\n", inet_ntoa(filter->sour_filter.ip), filter->sour_filter.mask, inet_ntoa(filter->dest_filter.ip), filter->dest_filter.mask);

        if (!strcmp(action, "accept"))
            filter->action = ACCEPT;
        if (!strcmp(action, "deny"))
            filter->action = DENY;
        printf("%s source %s %d %d destination %s %d %d\n", action, sour_ip, (filter->sour_filter.mask), (filter->sour_filter.port), dest_ip, (filter->dest_filter.mask), (filter->dest_filter.port));
        cur_p_filter->next = filter;
        cur_p_filter = cur_p_filter->next;
    }

    if (0 == feof)
    {
        // 未读到文件末尾
        printf("fgets error\n");
        return -1;
    }
    fclose(fp);

    return line_num;
}

bool pass_with_filter(struct FILTER *filter, char *packet)
{
    while (filter != NULL)
    {
        if ((u_int16_t) * (packet + 12) == 0x0008)
        {
            u_int32_t tmp_sour_ip = 0;
            u_int32_t tmp_dest_ip = 0;
            memcpy(&tmp_sour_ip, (packet + 26), 4);
            memcpy(&tmp_dest_ip, (packet + 30), 4);

            mask_ip(&tmp_sour_ip, filter->sour_filter.mask);
            mask_ip(&tmp_dest_ip, filter->sour_filter.mask);

            if (filter->sour_filter.ip.s_addr == 0 || tmp_sour_ip == filter->sour_filter.ip.s_addr)
            {
                if (filter->dest_filter.ip.s_addr == 0 || tmp_dest_ip == filter->dest_filter.ip.s_addr)
                {
                    if (filter->action == ACCEPT)
                    {
                        return true;
                    }
                }
            }
        }
        filter = filter->next;
    }

    return false;
}

// int main(int argc, char *argv[])
// {
//     struct FILTER filter;
//     int line_num = read_line(argv[1], &filter);
//     printf("line_num = %d\n", line_num);
//     return 0;
// }
